package com.spzx.cart.service.impl;

import com.spzx.cart.api.domain.CartInfo;
import com.spzx.cart.service.ICartService;
import com.spzx.common.core.constant.SecurityConstants;
import com.spzx.common.core.context.SecurityContextHolder;
import com.spzx.common.core.domain.R;
import com.spzx.common.core.exception.ServiceException;
import com.spzx.product.api.RemoteProductService;
import com.spzx.product.api.domain.ProductSku;
import com.spzx.product.api.domain.vo.SkuPrice;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Slf4j
public class CartServiceImpl implements ICartService {

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    private RemoteProductService remoteProductService;

    private String getCartKey(Long userId) {
        //定义key user:userId:cart
        return "user:cart:" + userId;
    }

    @Override
    public void addToCart(Long skuId, Integer skuNum) {
        long userId = SecurityContextHolder.getUserId();
        String cartKey = getCartKey(userId);
        String hashKey = skuId.toString();

        BoundHashOperations<String, String, CartInfo> hashOperations = redisTemplate.boundHashOps(cartKey);
        Integer threshold = 99;
        if (hashOperations.hasKey(hashKey)) {
            CartInfo cartInfo = hashOperations.get(hashKey);
            int totalNum = cartInfo.getSkuNum() + skuNum;
            cartInfo.setSkuNum(totalNum > threshold ? threshold : totalNum);
            cartInfo.setUpdateTime(new Date());
            hashOperations.put(hashKey, cartInfo);
        }else{
            Long size = hashOperations.size();
            if (size >= 50) {
                throw new RuntimeException("商品种类数量超过50件上限！");
            }
            CartInfo cartInfo = new CartInfo();
            cartInfo.setCreateTime(new Date());
            cartInfo.setUserId(userId);
            cartInfo.setSkuId(skuId);
            cartInfo.setSkuNum(skuNum);
            R<ProductSku> productSkuR = remoteProductService.getProductSku(skuId, SecurityConstants.INNER);
           if(productSkuR.getCode() ==R.FAIL){
               throw new ServiceException(productSkuR.getMsg());
           }
           ProductSku productSku = productSkuR.getData();
            cartInfo.setSkuName(productSku.getSkuName());
            cartInfo.setThumbImg(productSku.getThumbImg());
            cartInfo.setCartPrice(productSku.getSalePrice());
            cartInfo.setSkuPrice(productSku.getSalePrice());
            hashOperations.put(hashKey,cartInfo);
        }
    }

    @Override
    public List<CartInfo> cartList() {
        long userId = SecurityContextHolder.getUserId();
        String cartKey = getCartKey(userId);
        BoundHashOperations<String, String, CartInfo> hashOperations = redisTemplate.boundHashOps(cartKey);
       List <CartInfo> cartInfoList = hashOperations.values();
       if(!CollectionUtils.isEmpty(cartInfoList)) {
           List<Long> skuIdList = cartInfoList.stream().map((cartInfo) -> cartInfo.getSkuId()).toList();
           R<List<SkuPrice>> skuPriceListR = remoteProductService.getSkuPriceList(skuIdList, SecurityConstants.INNER);
           if(R.FAIL == skuPriceListR.getCode())   {
               throw new ServiceException(skuPriceListR.getMsg());
           }
           List<SkuPrice> skuPriceList = skuPriceListR.getData();
           Map<Long, BigDecimal> skuIdToSalePriceMap = skuPriceList.stream()
                   .collect(Collectors.toMap(SkuPrice::getSkuId, SkuPrice::getSalePrice));
           for(CartInfo cartInfo : cartInfoList) {
//               skuPriceList.stream().filter((skuPrice)->{
//                   return skuPrice.getSkuId().equals(cartInfo.getSkuId());
//               }).findFirst().ifPresent((skuPrice)->{
//                   cartInfo.setSkuPrice(skuPrice.getSalePrice());
//               });
               cartInfo.setSkuPrice(skuIdToSalePriceMap.get(cartInfo.getSkuId()));
                   }
           return cartInfoList;
               }
       return new ArrayList<>();

    }

    @Override
    public void deleteCart(Long skuId) {
        long userId = SecurityContextHolder.getUserId();
        String cartKey = getCartKey(userId);
        BoundHashOperations<String, String, CartInfo> hashOperations = redisTemplate.boundHashOps(cartKey);
    if(hashOperations.hasKey(skuId.toString())){
        hashOperations.delete(skuId.toString());

    }

    }

    @Override
    public void checkCart(Long skuId, Integer isChecked) {
        long userId = SecurityContextHolder.getUserId();
        String cartKey = getCartKey(userId);

        String hashKey = skuId.toString();
        BoundHashOperations<String, String, CartInfo> hashOperations = redisTemplate.boundHashOps(cartKey);
        // 先获取用户选择的商品
        if (hashOperations.hasKey(hashKey)) {
            CartInfo cartInfoUpd = hashOperations.get(hashKey);
            // cartInfoUpd 写会缓存
            cartInfoUpd.setIsChecked(isChecked);
            // 更新缓存
            hashOperations.put(hashKey, cartInfoUpd);

        }
    }

    @Override
    public void allCheckCart(Integer isChecked) {
        long userId = SecurityContextHolder.getUserId();
        String cartKey = getCartKey(userId);

        BoundHashOperations<String, String, CartInfo> hashOperations = redisTemplate.boundHashOps(cartKey);
       if(hashOperations.size() > 0) {
           List<CartInfo> cartInfoList = hashOperations.values();
           for (CartInfo cartInfo : cartInfoList) {
               cartInfo.setIsChecked(isChecked);
               hashOperations.put(cartInfo.getSkuId().toString(), cartInfo);
           }
       }

    }

    @Override
    public void clearCart() {
        long userId = SecurityContextHolder.getUserId();
        String cartKey = getCartKey(userId);
        if(redisTemplate.hasKey(cartKey))
        redisTemplate.delete(cartKey);
    }

    private static String getCartKey(long userId){
        return "user:cart:"+userId;
    }
}
